package fr.gmdev.mail.fonction.mail;

import java.util.*;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.*;

import java.io.*;
import javax.mail.internet.*;

import fr.gmdev.mail.util.StreamUtility;

public class PieceJointe {

    private Map header;
    private String filename;
    private String contentType;
    private byte[] contenu;

    public static PieceJointe getInstance(Part p, boolean partBinaire) throws MessagingException, IOException{
        String contentType = p.getContentType();
        String filename = p.getFileName();

        Enumeration enu = p.getAllHeaders();
        Map header = new HashMap();
        while (enu.hasMoreElements())
        {
            Header h = (Header)enu.nextElement();
            header.put(h.getName(),h.getValue());
        }
        byte[]contenu = null;
        Object contenuObj = null;
        try {
            contenuObj = p.getContent();
        }
        catch (UnsupportedEncodingException ex) {
            patchEncodingProblem(p);
            contenuObj = p.getContent();
        }

        if (contenuObj instanceof String)
        {
            contenu = ((String)contenuObj).getBytes();
        } else if (contenuObj instanceof byte[]) {
            contenu = (byte[])contenuObj;
        } else if (contenuObj instanceof InputStream) {
            int taillePrevisionnelle = Math.max(p.getSize()+1,1024*32);
            contenu = StreamUtility.inputStreamToByte((InputStream)contenuObj,taillePrevisionnelle);
        } else if (contenuObj instanceof Multipart) {
            Multipart contenuPart = (Multipart)contenuObj;

            FileOutputStream fis = null;
            for (int i = 0; i < contenuPart.getCount(); i++) {
            	fis = new FileOutputStream ("/h:/var/file"+i+"txt");
//                ByteArrayOutputStream bos = StreamUtility.getOutputStream(contenuPart.getBodyPart(i).getSize());
                contenuPart.getBodyPart(i).writeTo(fis);
            }
            
            ByteArrayOutputStream bos = StreamUtility.getOutputStream(p.getSize());
            contenuPart.writeTo(bos);
            contenu = bos.toByteArray();
            bos.close();
            bos=null;
        } else if (contenuObj instanceof Part)
        {
            Part contenuPart = (Part)contenuObj;
            ByteArrayOutputStream os = StreamUtility.getOutputStream(p.getSize());
            contenuPart.writeTo(os);
            contenu = os.toByteArray();
            os.close();
            os = null;
        } else {
            throw new ParseException("Le contenu de la piece attachee n'est pas reconnu " + contenuObj.getClass().getName());
        }
        if (!partBinaire){
            StreamUtility.convertOEM2ANSI(contenu);
        }
        return new PieceJointe(header,filename,contentType,contenu);
    }

    private PieceJointe(Map header,String filename,String contentType,byte[] contenu) {
        this.header=header;
        this.filename=filename;
        this.contentType=contentType;
        this.contenu=contenu;
    }


    public String getContentType() {
        return contentType;
    }
    public byte[] getContenu() {
        return contenu;
    }
    public String getFilename() {
        return filename;
    }
    public Map getHeader() {
        return header;
    }

 
 
    public boolean isVide() {
        return contenu==null||contenu.length==0;
    }

    public static void patchEncodingProblem(Part p) throws MessagingException
    {
        String [] header = p.getHeader("Content-Type");
        if (header!=null)
        {
            p.removeHeader("Content-Type");
            int index1, index2;
            for (int i =0 ;i <header.length ;i++)
            {
                index1 =  header[i].toLowerCase().indexOf("charset");
                if (index1!=-1)
                {
                    String newHeader = header[i].substring(0,index1);
                    if ((index2=newHeader.lastIndexOf(";"))!=-1)
                    {
                        newHeader=header[i].substring(0,index2);
                    }
                    p.addHeader("Content-Type",newHeader);
                } else
                {
                    p.addHeader("Content-Type",header[i]);
                }
            }
        }
    }


}
